#!/bin/bash
#!/usr/bin/env bash
#THIS DRIVER WRITTEN BY MATTHEW VONA ARB FOR THE Environics 9100
#FOR QUESTIONS WRITE mailto:mvona@arb.ca.gov
#UPDATED 9/3/2009-MJV

# THIS IS THE FUNCTION CALLED IN THE EVENT THAT CTRL+C IS PRESSED

cleanup()
{
	echo "Caught Signal ... cleaning up."
	rm -f Data/.locked > /dev/null	
	echo "Done cleanup ... quitting."
	exit 1
}
#BEGIN WRITE
#THIS FUNCTION HANDELS READ RIGHT HANDSHAKES BETWEEN VARIOUS DRIVERS
#IN GENERAL, THE DATA IS PLACED IN THE VARIABLE $TIMESTAMP PRIOR TO CALL
#NEXT, IT OPENS THE DATA DIRECTORY AND LOOKS FOR THE .locked FILE
#IF IT EXISTS, IT HANGS OUT UNTIL IT DOESN'T EXIST. AT THAT POINT
#IT CREATES A .locked FILE, AND APPENDS TO THE DATA RECORD.
#FINALLY IT REMOVES THE .locked FILE IT HAS CREATED.
#written by MJV
write()
{
#CONFIRM THAT THERE IS NO HIDDEN FILE CALLED '.locked'
	while [ -e "Data/.locked" ];
		do
			sleep .2;
		done	
	echo "LOCKED" > "Data/.locked";
	if !(echo $timestamp >> "Data/$datafile"); then
		{
			echo "GENERAL FAILURE WRITING TO RECORD: $#";
			exit 1;
		}
	fi
	if !(echo $timestamp | diag); then
		{
		echo "GENERAL FAILURE RUNNING DIAGNOSTICS: $#";
		cleanup;
		}
	fi
	if !(echo $timestamp | enviro_diag); then
		{
		echo "GENERAL FAILURE RUNNING ENVIRONICS SPECIFIC DIAGNOSTICS: $#";
		cleanup;
		}
	fi
	if !(rm -f "Data/.locked"); then
		{
			echo "GENERAL FAILURE REMOVING LOCK: $#";
			exit 1;	
		}
	fi
	if !(timestamp=""); then
		{
		echo "GENERAL FAILURE CLEARING WRITE BUFFER: $#";
		cleanup;
		}
	fi	
}
###DIAGNOSTICS ROUTINE CALLED BY WRITE
##WRITTEN by MJV
diag()
{
    thishour=`date "+%H"`
    thistime=`date "+%H%M"`
    thisalert="errors$thishour"

    if [ "$thistime" != "0350" ] && [ "$thistime" != "0351" ] && [ "$thistime" != "0352" ] && [ "$thistime" != "0353" ]
    then
	this_name=$(cat resources/environics9100_drv/.usr$instance | grep -o "\-r [A-Za-z0-9]*" | awk '{ print $2 }')
	awk -v name=${this_name} -v error_time=${thistime} '{
	if (/LOW FLOW/ || /LOW OZONE/)
	 { print "An error of Low Flow or Low Ozone was displayed on the " name " @ " error_time }
	}' >> "Data/$thisalert"
    fi    
}

#SPECIFIC DIAGNOSTIC ROUTINES FOR THE ENVIRONICS
#THE ENVIRONICS DATA STREAM IS NOT FIXED. THEREFORE, WE ISOLATE
#THE TESTED VARIABLES USING GREP PATTERN MATCHING.
#9/3/2009 MJV UPDATED TO LOOK FOR LOW FLOW RANGES OR HIGH FLOW RANGES 
enviro_diag()
{
thishour=`date "+%H"`
thistime=`date "+%H%M"`
thisalert="errors$thishour"

if [ "$thistime" != "0350" ] && [ "$thistime" != "0351" ] && [ "$thistime" != "0352" ] && [ "$thistime" != "0353" ]
then
    this_name=$(cat resources/environics9100_drv/.usr$instance | grep -o "\-r [A-Za-z0-9]*" | awk '{ print $2 }')
    grep -o "generator flow [0-9][0-9][0-9]\.[0-9]" | awk -v stamp=`date "+%m-%d-%Y_%H:%M"` -v name=$this_name '{ 
	if ($3<450)
		{ print name " FLOW IS LOW " $3 " is less than 450 "stamp }
	if ($3>=550)
		{ print name " FLOW IS HIGH" $3 " is more than 550 "stamp }
	 }' >> "Data/$thisalert"
fi
}

#THIS IS THE ACTUAL COMMUNICATION WITH THE INSTRUMENT
#WRITTEN BY MJV
runit()
{
today=`date "+%Y-%d-%m"`
#THIS IS THE NAME OF THE DATA FILE RIGHT NOW
datafile="$saroad-$today"
resp=$(timeout 20 sjinn -b $bd_rt -d $dvc_prt -s $cmnd1 -r$rsp_lngth -w$wt_rsp1 $p8n1 $dtr $ctr | sed 's/\.\[[0-9][0-9]//g' | sed 's/\;[0-9][0-9]H//g' | sed 's/           //g')
#CREATE A VALUE FOR THE ENVIRONICS EQUAL TO THE PRODUCT OF THE SEQUENCE TIMES 10 PLUS THE STEP NUMBER
sequence=`echo $resp | grep -o "SEQ [0-9]" | sed 's/SEQ //g'`
item=`echo $resp | grep -o "ITEM [0-9]" | sed 's/ITEM //g'`
value="${sequence}${item}"
if [ -z $value ]; then
{
value='0'
}
fi
timestamp="$rprt_nm::`date "+%m-%d-%Y_%H:%M"`:::$resp:::cal=$value"
write 
}
#THIS IS THE FUNCTION RUN IN THE EVENT THAT THE REQUIRED PARAMETERS
#ARE NOT ENTERED.
usage()
{
clear
cat << EOF
usage: $0 options
OPTIONS:
-h	display help
-r	rprt_nm [rn]
-d	dvc_prt [eg, /dev/ttyS0, /dev/ttyUSB1] 
-b	bd_rt [2400,4800,9600,etc.]
-c	cmnd1
-w	wt_rsp1 [seconds]
-l	rsp_lngth [characters]
-s	SAROAD number of the station
-t	DTR=[ON/OFF] (OPTIONAL)
-C	CTR=[ON/OFF] (OPTIONAL)
-p	p8n1=[ON/OFF] (OPTIONAL)
-I 	instance
-F      Flow Rate Set Point
EOF
}
#HELP FUNCTION GIVES BACKGROUND ON THIS DRIVER
help_me ()
{
clear
cat .help
exit 0
}
def_opts ()
{
clear
cat .options
}

	##CLEAR ALL VARIABLES               
rprt_nm= ; dvc_prt= ; bd_rt= ; cmnd1= ; wt_rsp1= ; bd_rt= ; rsp_lngth=
dtr=
ctr=
p8n1=
saroad=
instance=1
	##loop through all variables and parameters
while getopts “hr:s:d:b:c:w:l:t:C:p:I:” OPTION
do
case $OPTION in
s)
saroad=$OPTARG
;;
r)
rprt_nm=$OPTARG
;;
d)
dvc_prt=$OPTARG
;;
b)
bd_rt=$OPTARG
;;
c)
cmnd1=$OPTARG
;;
w)
wt_rsp1=$OPTARG
;;
l)
rsp_lngth=$OPTARG
;;
t)
dtr=$OPTARG
;;
C)
ctr=$OPTARG
;;
I)
instance=$OPTARG
;;
p)
p8n1=$OPTARG
;;
F)
flow_stpt=$OPTARG
;;
h)
help_me
exit 1
;;
*)
usage
exit 1
;;
esac
done
	#CHECK FOR THE CRITICAL PARAMETERS, IF THEY ARE NOT PRESENT THEN
	#RUN THE USAGE FUNCTION WHICH RETURNS THE INSTRUCTIONS FOR PROPER USAGE
if [ -z "$rprt_nm" ] || [ -z "$dvc_prt" ] || [ -z "$bd_rt" ] || [ -z "$cmnd1" ] ||
[ -z "$wt_rsp1" ] || [ -z "$rsp_lngth" ] || [ -z "$saroad" ] || [ -z "$instance" ]
	then
		{
		usage
		exit
		}
fi
##Translate $p8n1 = on into --p8n1 for use in passing to sjinn
##also do this for ctr, and dtr
if [ "$dtr_val" = "on" ]; then
 	dtr="--dtr" 
fi
if [ "$ctr_val" = "on" ]; then
 	ctr="--ctr"
fi
if [ "$p8n1_val" = "on" ]; then
 	p8n1="-p8n1"
fi
	#INITIALIZED THE RAN VARIABLE. THIS IS USED TO TOGGLE THE TIMER GATE
ran=0
	#TRAP CTRL+C
trap cleanup 1 2 3 6 9 15
	#SETUP THE OPERATING LOOP
while :
do
	#SET THE SECOND VARIABLE AS THE SECOND VALUE FROM THE DATA STAMP 
second=`date "+%S"`
	#IF THE SECOND VALUE IS LESS THAN 02, BEGIN RUNNING
if [ "$second" -eq "00" ] && [ "$ran" -eq "0" ]; then
	{
	#RUN THE RUNIT FUNCTION
		runit
	#TOGGLE THE RAN VARIABLE SO THAT THE PROCESS WILL NOT REPEAT
	#UNTIL THE BEGINNING OF THE NEXT MINUTE.
		ran=1
	#WAIT FOR COMPLETION OF THE RUNIT FUNCTION AND THE VARIABLE
	#SET
		wait
	}
	#IF THE SECOND VALUE IS GREATER THAT 02, RESET RAN TO 0
	#AND WAIT ONE SECOND BEFORE CHECKING AGAIN
else 
	{
	#WAIT half a second SECOND
		sleep .5
	#SET RAN TO 0
		ran=0
	}
fi
done;
exit;

